from nonebot.plugin import PluginMetadata
from nonebot.exception import MatcherException
from nonebot import get_driver
from nonebot.permission import SUPERUSER
# from .config import Config
from nonebot import on_notice, on_request, on_keyword, on_message, on
from nonebot.log import logger
from nonebot.typing import T_State
from nonebot.adapters.onebot.v11 import Bot, Event, MessageEvent, NoticeEvent, RequestEvent, GroupIncreaseNoticeEvent, MessageSegment, GroupRequestEvent, GroupDecreaseNoticeEvent, PrivateMessageEvent, GroupMessageEvent
from .config import *
import re
import json
import datetime

__plugin_meta__ = PluginMetadata(
    name="嗨群组管理",
    description="简单的群组管理",
    usage="暂无",
    type="群组管理",
    # 发布必填，当前有效类型有：`library`（为其他插件编写提供功能），`application`（向机器人用户提供功能）。
    homepage="暂无",
    # 发布必填。
    # config=Config,
    # 插件配置项类，如无需配置可不填写。
    supported_adapters={
        "~onebot.v11",
    },
    # 支持的适配器集合，其中 `~` 在此处代表前缀 `nonebot.adapters.`，其余适配器亦按此格式填写。
    # 若插件可以保证兼容所有适配器（即仅使用基本适配器功能）可不填写，否则应该列出插件支持的适配器。
)

global_config = get_driver().config
config = Config.parse_obj(global_config)
"""载入配置"""

# for key, value in dict(config).items():
#     logger.debug(f"{key} = {value}")

for i in config:
    logger.debug(f'{i},{type(i[0])},{type(i[1])}')

logger.debug(f'{config.ADMIN} <--超管?')
"""插件管理员调试"""

db = DB_Utils('./ts.db')
"""db数据库"""


def _is_DEBUG() -> bool:
    """调试模式"""
    return config.DEBUG


def _join_req(event: Event):
    """加群请求事件"""
    return isinstance(event, GroupRequestEvent)


def _join_nts(event: Event):
    """加群事件"""
    return isinstance(event, GroupIncreaseNoticeEvent)


def _leave_nts(event: Event):
    """退群事件"""
    return isinstance(event, GroupDecreaseNoticeEvent)


def _private_msg(event: Event):
    """私聊消息事件"""
    return isinstance(event, PrivateMessageEvent)


def _group_msg(event: Event):
    """群消息事件"""
    return isinstance(event, GroupMessageEvent)


def _msg_event(event: Event):
    """消息事件"""
    return isinstance(event, MessageEvent)


def _nts_event(event: Event):
    """通知事件"""
    return isinstance(event, NoticeEvent)


def _req_event(event: Event):
    """请求事件"""
    return isinstance(event, RequestEvent)


leave = on_notice(rule=_leave_nts, priority=config.PRIORITY)
"""监测退群事件"""
join = on_notice(rule=_join_nts, priority=config.PRIORITY)
"""监测入群事件"""
join_checker = on_request(rule=_join_req, priority=config.PRIORITY)
"""监测加群申请"""
get_group_msg = on_message(rule=_group_msg, priority=config.PRIORITY)
"""私聊消息监测"""
get_person_msg = on_message(rule=_private_msg, priority=config.PRIORITY)
"""群聊消息监测"""
msgs = on(rule=_msg_event, priority=config.PRIORITY)
"""消息事件监测"""
ntss = on(rule=_nts_event, priority=config.PRIORITY)
"""通知事件监测"""
reqs = on(rule=_req_event, priority=config.PRIORITY)
"""请求事件监测"""
list_black_list = on_keyword(rule=_group_msg,
                             priority=config.PRIORITY,
                             keywords={'/黑名单'},
                             permission=SUPERUSER)
"""列出群黑名单命令"""
plugin_init = on_keyword(permission=SUPERUSER,
                         priority=1,
                         keywords={"/初始化"},
                         rule=_private_msg)
"""初始化插件命令"""


@plugin_init.handle()
async def _(bot: Bot, event: MessageEvent):
    """初始化插件"""
    try:
        res = await bot.get_group_list()
        logger.debug(res)
        groups = {
            "表名": "groups",
            "群号": "group_id",
            "群名称": "group_name",
            "群备注": "group_memo",
            "创建时间": "group_create_time",
            "群成员数": "member_count",
            "群容量": "max_member_count",
            "开关状态": "status",
            "消息记录开关": "msg_record_status",
            "更新时间": "updated_at",
            "屏蔽词": "bad_words",
            "黑名单": "black_list",
            "插件管理员": "plugin_admin",
        }
        db._init_table(groups, PRIMARY=True)
        rq_ls = []
        for i in res:
            group_id = i['group_id']
            group_name = i['group_name']
            max_member_count = i['max_member_count']
            member_count = i['member_count']
            rq_ls.append(f'{group_name}:{group_id} {member_count}')
            init_data = {
                "group_id": group_id,
                "group_name": group_name,
                "max_member_count": max_member_count,
                "member_count": member_count,
                "status": "off",
                "msg_record_status": "off",
                "updated_at": get_now(),
                # "bad_words": "",
                # "black_list": ""
            }
            db.insert_row(
                table_name='groups',
                values=init_data,
            )
            # 消息记录表初始化
            msg_table_dict = {
                "表名": f'chat_data_by_{group_id}',
                "QQ": "user_id",
                "昵称": "nickname",
                "群昵称": "card",
                "消息": "message",
                "消息ID": "message_id",
                "创建时间": "created_at"
            }
            db._init_table(msg_table_dict)
        rs = '\n'.join(rq_ls)
        await plugin_init.finish(
            message=MessageSegment.text(f'初始化完成,加载信息如下:\n{rs}'))
    except MatcherException:  #正常通过抛出异常结束事件,请无视
        raise
    except Exception as e:
        # await plugin_init.finish(message=MessageSegment.text(f'初始化失败:\n{e}'))
        logger.error(f'初始化失败:\n{e}')


@reqs.handle()
async def _(event: Event):
    """请求事件反馈"""
    logger.debug(f"收到请求事件 =={event}== ")
    try:
        logger.debug(f"""
                     ================================================================
                     neme: {event.get_event_name()}
                     ================================================================
                     """)
    except Exception as e:
        logger.error(f"处理请求事件失败: {e}")


@ntss.handle()
async def _(event: Event):
    """通知事件反馈"""
    logger.debug(f"收到通知事件 =={event}== ")
    try:
        logger.debug(f"""
                     ================================================================
                     neme: {event.get_event_name()}
                     type: {event.notice_type}
                     ================================================================
                     """)
    except Exception as e:
        logger.error(f"处理通知事件失败: {e}")


@msgs.handle()
async def _(event: Event):
    """消息事件反馈"""
    logger.debug(f"收到消息事件 =={event}== ")
    try:
        if _is_DEBUG():
            logger.debug(f"""
                 ================================================================
                 user_id: {event.user_id}
                 message_type: {event.message_type}
                 message_id: {event.message_id}
                 message: {event.message}
                 original_message: {event.original_message}
                 raw_message: {event.raw_message}
                 sender: {event.sender}
                 nickname: {event.sender.nickname}
                 gruop_nickname: {event.sender.card}
                 ================================================================
                 """)
        else:
            pass
    except Exception as e:
        logger.error(f"事件解析失败: {e}")


@get_person_msg.handle()
async def _(event: PrivateMessageEvent, bot: Bot):
    """私聊消息反馈"""
    logger.info(f"收到来自{event.get_user_id()}消息: {event.get_message()}")


@get_group_msg.handle()
async def _(event: GroupMessageEvent, bot: Bot):
    """群聊消息反馈-记录"""
    logger.info(f"收到{event.group_id}群消息: {event.get_message()}")
    user_id = str(event.user_id)
    message = str(event.message)
    message_id = str(event.message_id)
    nickname = event.sender.nickname
    card = event.sender.card
    insert_row_data = {
        "user_id": user_id,
        "nickname": nickname,
        "card": card,
        "message": message,
        "message_id": message_id,
        "created_at": get_now()
    }
    group_id = str(event.group_id)
    try:
        zl = 'msg_record_status'
        _check = str(
            db._exec(f'''SELECT {zl} FROM groups where group_id = {group_id}'''
                     )[0][0])
        logger.debug(f'群消息记录功能:{_check}')
        if _check == 'on':
            db.insert_row(f'chat_data_by_{group_id}', insert_row_data)

        else:
            group_name = db._exec(
                f'SELECT group_name FROM groups WHERE group_id = {group_id}'
            )[0][0]
            logger.info(f"群  {group_name}  未开启记录功能--消息逃逸--->{insert_row_data}")
    except Exception as e:
        logger.error(f"插入数据库失败: {e}")


@list_black_list.handle()
async def _(event: GroupMessageEvent, bot: Bot):
    """黑名单指令反馈"""
    logger.info(f"收到指令: {event}")
    # for i in config.Black_list:
    #     logger.debug(i)
    result_string = '\n'.join(config.Black_list)
    if _is_DEBUG():
        await bot.send_private_msg(
            user_id=config.ADMIN[0],
            message=MessageSegment.text(f"当前黑名单列表:\n {result_string}"))
    else:
        pass
        # await list_black_list.finish(MessageSegment.text(f"当前黑名单列表:\n {result_string}"))


@join_checker.handle()
async def do_checker(bot: Bot, event: GroupRequestEvent):
    """加群审核反馈"""
    logger.debug(f'加群验证事件-> |{event}')
    logger.debug(event.get_event_description())
    raw = json.loads(event.json())
    group_id = str(event.group_id)
    flag = raw['flag']
    sub_type = raw['sub_type']
    if sub_type == 'add':
        comment = raw['comment']
        word = re.findall(re.compile('答案：(.*)'), comment)[0]
        user_id = event.user_id
        logger.info(f'监管群 - 监测到 {user_id} 请求加入 {group_id}, 验证新消息 "{word}"')
        if (event.group_id in config.GROUPS):  # 需要在监管群内,才触发黑名单验证
            # 在监管群内才进行匹配答案关键字
            if (str(word) in config.Allow_words[f'{group_id}']):
                logger.info(f'{user_id}答案匹配正确, 开始验证黑名单...')
                if user_id not in config.Black_list:  # 未在黑名单
                    await bot.set_group_add_request(
                        flag=flag,
                        sub_type=sub_type,
                        approve=True,
                        reason=" ",
                    )
                    logger.info(f'已同意 {user_id} 加入 {group_id} 群 ')
                else:  # 在黑名单
                    await bot.set_group_add_request(
                        flag=flag,
                        sub_type=sub_type,
                        approve=False,
                        reason="您曾经被纳入群管黑名单",
                    )
                    # --->chat in group
                    await join_checker.finish(f"{user_id}欲加群,曾被纳入黑名单列表!拒绝")
                    logger.info(f'已拒绝 {user_id} 加入 {group_id} 群 ')
            else:  # 未匹配到答案关键字
                await join_checker.finish("加群为关键词未验证通过,请管理手动处理")
        else:  # 未在监管群内,不触发黑名单校验规则,也不进行答案检验,直接通过
            logger.info(
                f'未监管群 - 监测到 {user_id} 请求加入 {group_id}, 验证新消息 "{word}"')
            await bot.set_group_add_request(
                flag=flag,
                sub_type=sub_type,
                approve=True,
                reason=" ",
            )
            logger.info(f'已同意 {user_id} 加入 {group_id} 群 ')


@join.handle()
async def group_increase_handle(bot: Bot, state: T_State,
                                event: GroupIncreaseNoticeEvent):
    """加群通知事件反馈"""
    insert_row_data = {
        "user_id": event.user_id,
        "nickname": "join_in_group",
        "card": "join_in_group",
        "message": "加群事件",
        "message_id": "join_in_group",
        "created_at": get_now()
    }
    group_id = str(event.group_id)
    zl = 'msg_record_status'
    _check = str(
        db._exec(f'''SELECT {zl} FROM groups where group_id = {group_id}''')[0]
        [0])
    if _check == 'on':
        db.insert_row(f'chat_data_by_{group_id}', insert_row_data)
    else:
        group_name = db._exec(
            f'SELECT group_name FROM groups WHERE group_id = {group_id}')[0][0]
        logger.info(f"群  {group_name}  未开启记录功能--加群消息逃逸--->{insert_row_data}")


@leave.handle()
async def group_decrease_handle(bot: Bot, state: T_State,
                                event: GroupDecreaseNoticeEvent):
    """退群通知反馈"""
    logger.debug(f'退群检测事件-> |{event}')
    logger.debug(event.get_event_description())
    logger.info(f'配置群清单|{config.GROUPS}')
    user_id = str(event.user_id)
    group_id = str(event.group_id)
    """加群通知事件反馈"""
    insert_row_data = {
        "user_id": event.user_id,
        "nickname": "leave_group",
        "card": "leave_group",
        "message": "退群事件",
        "message_id": "leave_group",
        "created_at": get_now()
    }
    db.insert_row(f'chat_data_by_{group_id}', insert_row_data)
    add_black(user_id, group_id)
    if _is_DEBUG():
        await bot.send_private_msg(
            user_id=config.ADMIN[0],
            message=MessageSegment.text(
                f'user {event.user_id} leaved grop {event.group_id}'))
        """私信给管理"""
    else:
        await leave.finish(MessageSegment.text(f'很遗憾 {event.user_id} 退群了!\n'))
